/*
 * @Author: quit
 * @Date: 2023-03-17 05:21:11
 * @LastEditTime: 2023-03-19 13:13:36
 * @Descripttion: 装饰器
 * 随着TS和ES6里引入类,在一些场景下我们需要额外的特性来支持标注或修改类及成员。
 * 装饰器(Decorators)允许向一个现有的对象添加新的功能,同时又不改变其结构
 * 装饰器是一种特殊类型的声明,它能够被附加到 类声明, 方法, 访问符, 属性, 参数上,所以有5种装饰器.它可以在不修改代码自身的前提下,给已有代码添加额外的行为.
 * 装饰器使用 @expression 在求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入
 * 普通装饰器(无法传参),装饰器工厂(可以传参),一般都是一这种方式;给装饰器加上参数,或者叫做 注解 或者叫元数据
 * @notice:
 */

/**
 * 普通装饰器
 * 参数 param 为下面类 SideBar 的 constructor
 */
// function Component(param: any) {
//     console.log('装饰器函数');
//     console.log(param);
// }
// @Component
// class SideBar {}

/**
 * 装饰器工厂
 * 帮助用户传递可供装饰器使用的参数;演算顺序为由顶至下,执行顺序为由低向上
 * 装饰器对类的行为改变,是代码编译时发生的(不是在TS的编译阶段,是在JS的执行编译阶段),并不是在运行阶段,这意味着,装饰器能在编译阶段运行代码,也就是装饰器的本质就是编译时执行的函数
 */
// function Component(param: any) {
//     return function (target: any) {
//         console.log('可以传参');
//         console.log(param, 'param'); // 参数
//         console.log(target, 'target'); // 类的 构造函数本身
//     };
// }
// @Component({ templateURL: 'a', styleURL: 'b' })
// class SideBar {}

/**
 * @description: 属性装饰器
 * 表达式会在运行时当做函数被调用,有两个参数
 * 1、对静态成员来说是构造函数,对实例成员是原型对象
 * 2、当前属性名称
 * 静态成员的target就是构造函数本身;对于实例成员是类的构造函数的原型对象
 */
function Input(param?: any): Function {
    return function (target: any, attr: any) {
        // console.log('参数', param);
        // console.log('实例对象与当前数组名称', target, attr);
        target[attr] = param;
    };
}
class _SideBar {
    constructor() {}
    @Input('aa') public list: Array<number>;
    // @Input('bb') public static goods: Array<number>;
}
let v1 = new _SideBar();
console.log(v1.list);

export {};
